package it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.managers;

import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.player.SimplePlayer;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.pawn.Character;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.pawn.Inventory;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.pawn.items.Item;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.pawn.items.ItemFactory;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.pawn.stats.Role;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.pawn.stats.Stats;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.pawn.stats.StatsFactory;

public class StoreManager {

	public static final int NONE = -1;
	private SimplePlayer player;
	ItemFactory itmfct = ItemFactory.getInstance();
	private int currentSelectedBag = NONE;
	private Character currentSelectedChar = null;
	private Item currentSelectedItem = null;
	private int charPrice;
	int levels = 20;
    int startPrice = 1000;
    int lastPrice = 1000000000;
	
	
	public StoreManager(SimplePlayer player) {
		this.setPlayer(player);
	}

	public void calculateCharPrice(){
		
	    double B = Math.log((double)lastPrice / startPrice) / (levels - 1);
	    double A = (double)startPrice / (Math.exp(B) - 1.0);

	    int size = player.getCharacters().size();
	   charPrice = convertIntoInt(size,A,B) - convertIntoInt(size-1,A,B);
	}
	
	private int convertIntoInt(int i, double A, double B){
		int x = (int) (A * Math.exp(B * i));
			    int y = (int) Math.pow(10, (int) (Math.log(x) / Math.log(10) -2.2));
			    return (x / y) * y;
	}
	
	public boolean isCharBuyable(){
		
		return player.getGold() >= getCharPrice();
	}
	
	public boolean sellItem(int index){
		String removedItemName = currentSelectedChar.getInventory().removeItem(index);
		if(removedItemName == null)
			return false;
		
		Item removedItem = itmfct.getItem(removedItemName);
		currentSelectedChar.getStats().getCharacteristics().subtract(removedItem);
		player.addGold(itmfct.getItem(removedItemName).getSellPrice()); 
		return true;
	}
	
	public boolean isCharSellable(){
		return player.getCharacters().size() >1;
	}
	
	public boolean sellItem(){
		String removedItemName = currentSelectedChar.getInventory().removeItem(currentSelectedBag);
		if(removedItemName == null)
			return false;
		
		Item removedItem = itmfct.getItem(removedItemName);
		currentSelectedChar.getStats().getCharacteristics().subtract(removedItem);
		player.addGold(itmfct.getItem(removedItemName).getSellPrice()); 
		return true;
	}
	
	public void buyItem(){
		player.subtractGold(currentSelectedItem.getBuyPrice()); 
		Inventory inventory = currentSelectedChar.getInventory();
		if(currentSelectedBag != NONE && inventory.isSlotFree(currentSelectedBag))
			inventory.addItemByIndex(currentSelectedBag, currentSelectedItem.getName());
		else inventory.addItem(currentSelectedItem.getName());
		currentSelectedChar.getStats().getCharacteristics().sum(currentSelectedItem,true);
	}
	
	
	public Character buyCharacter(Role stats, String name){
		
		Character newChar = new Character(1, 0, player);
		newChar.setStats(new Role(stats));
		newChar.setName(name);

		player.addCharacter(newChar);
		player.subtractGold(getCharPrice());
		return newChar;
	}
	
	public void sellCharacter(int index){
		
		player.getCharacters().remove(index);
	}
	
	
	public boolean isCharListFull(){
		return (player.getCharacters().size() >= SimplePlayer.MAX_CHARACTERS );
	}
	
	public boolean isInventoryFull(){
		
			return currentSelectedChar.getInventory().isFull();
	
	}


	public int getCurrentSelectedBag() {
		return currentSelectedBag;
	}


	public void setCurrentSelectedBag(int currentSelectedBag) {
		this.currentSelectedBag = currentSelectedBag;
	}


	public Character getCurrentSelectedChar() {
		return currentSelectedChar;
	}


	public void setCurrentSelectedChar(Character currentSelectedChar) {
		this.currentSelectedChar = currentSelectedChar;
	}


	public SimplePlayer getPlayer() {
		return player;
	}


	public void setPlayer(SimplePlayer player) {
		this.player = player;
	}


	public boolean isPriceAffordable() {
		
		if(currentSelectedItem.getBuyPrice() > player.getGold())
			return false;
		
		return true;
	}

	public boolean isSlotFree(){
		
	return currentSelectedChar.getInventory().isSlotFree(currentSelectedBag);
	}
	
	public boolean isSlotFree(int index){
		return currentSelectedChar.getInventory().isSlotFree(index);
	}

	public Item getCurrentSelectedItem() {
		return currentSelectedItem;
	}


	public void setCurrentSelectedItem(Item currentSelectedItem) {
		this.currentSelectedItem = currentSelectedItem;
	}

	public int getCharPrice() {
		return charPrice;
	}

	public void setCharPrice(int charPrice) {
		this.charPrice = charPrice;
	}

	public boolean givesNegativeStats() {
		Stats newStats = currentSelectedChar.getStats().getCharacteristics().sum(currentSelectedItem);
		for(int i = 0; i<Stats.TOTAL_STATISTICS; i++){
			if(newStats.getStats(i) < 0)
				return true;
		}
		return false;
	}

	public boolean isCharNameUnique(String charName) {
		
		for(Character character : player.getCharacters())
			if(character.getName().equals(charName))
				return false;
		
		
		return true;
	}
	
	
}
